package password

import (
	"errors"
	"golang.org/x/crypto/bcrypt"
)

var (
	ErrPasswordTooShort = errors.New("密码长度至少8位")
	ErrPasswordTooWeak  = errors.New("密码必须包含大小写字母和数字")
)

// Hash 生成密码哈希
func Hash(password string) (string, error) {
	if err := validatePasswordStrength(password); err != nil {
		return "", err
	}

	hashedBytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}
	return string(hashedBytes), nil
}

// Verify 验证密码
func Verify(password, hash string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
	return err == nil
}

// 密码强度校验
func validatePasswordStrength(password string) error {
	if len(password) < 8 {
		return ErrPasswordTooShort
	}

	// 校验包含数字、大小写字母
	var (
		hasUpper  bool
		hasLower  bool
		hasNumber bool
	)

	for _, c := range password {
		switch {
		case c >= 'A' && c <= 'Z':
			hasUpper = true
		case c >= 'a' && c <= 'z':
			hasLower = true
		case c >= '0' && c <= '9':
			hasNumber = true
		}
	}

	if !(hasUpper && hasLower && hasNumber) {
		return ErrPasswordTooWeak
	}
	return nil
}
